#ifndef PARSER_INC
#define PARSER_INC

#include <string>
#include <cctype>
#include <cassert>
#include <fstream>
#include <iostream>

#include <vector>

#include "Defines.h"

typedef vector<string*> Tokens;

#define WORD    1
#define PHRASE  2

#define MIN_WORD    10
#define MIN_PHRASE  50

using namespace std;

/*
 * =====================================================================================
 *        Class:  Parser
 *  Description:  Classe que representa o Parser que lerá o arquivo de entrada
 * =====================================================================================
 */
class Parser
{

public:

    /*-----------------------------------------------------------------------------
     *  Contrói um Parser
     *-----------------------------------------------------------------------------*/
    Parser(ulong offset, ulong size, int type);

    virtual ~Parser();

    /*-----------------------------------------------------------------------------
     *  Obtem tokens de um bloco
     *-----------------------------------------------------------------------------*/
    Tokens* getTokens(string *block);

    /*-----------------------------------------------------------------------------
     *  Deleta os tokens
     *-----------------------------------------------------------------------------*/
    static void deleteTokens(Tokens **tokens);

    /*-----------------------------------------------------------------------------
     *  Imprime os tokens para debug
     *-----------------------------------------------------------------------------*/
    static void printTokens(ostream& os, Tokens *tokens);

    /*-----------------------------------------------------------------------------
     *  Retorna verdadeiro se o parser terminou sua execução
     *-----------------------------------------------------------------------------*/
    bool isFinished();

private:

    /*-----------------------------------------------------------------------------
     *  Verifica se determinado caracter c é separador (para palavras ou frases)
     *-----------------------------------------------------------------------------*/
    bool isSeparator(char c);

    /*-----------------------------------------------------------------------------
     *  Remove os espaços antes e depois da string
     *-----------------------------------------------------------------------------*/
    void trimString(string *str);

    /*-----------------------------------------------------------------------------
     *  Enum para máquina de estados do getToken
     *-----------------------------------------------------------------------------*/
    enum
    {
        IGNORE_FIRST, SKIP_SEPARATORS, APPEND_TOK
    };

    /*-----------------------------------------------------------------------------
     *  Quantidade a ser lida a partir de offset
     *-----------------------------------------------------------------------------*/
    ulong size;

    /*-----------------------------------------------------------------------------
     *  Quantidade de caracteres lidas do arquivo
     *-----------------------------------------------------------------------------*/
    ulong count;

    /*-----------------------------------------------------------------------------
     *  Tipo: 1 - palavra e 2 - frase
     *-----------------------------------------------------------------------------*/
    int type;

    /*-----------------------------------------------------------------------------
     *  Estado da Máquina de Estados para getTokens()
     *-----------------------------------------------------------------------------*/
    int state;

    /*-----------------------------------------------------------------------------
     *  String atual (realizando append) ou string cortada por causa do bloco
     *-----------------------------------------------------------------------------*/
    string *tok;

};

#endif
